package net.dreamlu.iot.mqtt.broker.handler.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.iot.mqtt.broker.enums.RedisKeys;
import net.dreamlu.iot.mqtt.broker.handler.TopicHandler;
import net.dreamlu.iot.mqtt.broker.model.PlayStatusDto;
import net.dreamlu.iot.mqtt.codec.MqttPublishMessage;
import net.dreamlu.iot.mqtt.core.server.MqttServerCreator;
import net.dreamlu.mica.core.utils.DateUtil;
import net.dreamlu.mica.redis.cache.MicaRedisCache;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.Objects;
import java.util.Set;

/**
 * @author: chenlf
 * @date: 2023/9/5
 * @description: PlayerStatusHandler
 **/
@Component
@RequiredArgsConstructor
@Slf4j
public class PlayerStatusHandler extends BaseHandler implements TopicHandler, SmartInitializingSingleton, DisposableBean {
    private MqttServerCreator serverCreator;
    private final ApplicationContext context;
    private final MicaRedisCache redisCache;
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public String topic() {
        return BASE_TOPIC_PATH + "/playStatus";
    }

    @Override
    public void handle(String clientId, MqttPublishMessage message) {
        try {
            PlayStatusDto playStatusDto = objectMapper.readValue(message.getPayload(), PlayStatusDto.class);
            if (Objects.equals("1", playStatusDto.getPlayStatus())) {
                redisCache.sAdd(getPlayerStatusRedisKey(), clientId);
                redisCache.set(getPlayerTimeRedisKey() + ":" + clientId, DateUtil.formatDateTime(new Date()));
            } else {
                redisCache.sRem(getPlayerStatusRedisKey(), clientId);
                redisCache.del(getPlayerTimeRedisKey() + ":" + clientId);
            }
        } catch (IOException e) {
            log.error("解析消息异常:{}", e.getMessage(), e);
        }


    }


    private String getPlayerStatusRedisKey() {
        return RedisKeys.CONNECT_PLAYE.getKey(serverCreator.getNodeName());
    }

    private String getPlayerTimeRedisKey() {
        return RedisKeys.CONNECT_PLAYE_TIME.getKey(serverCreator.getNodeName());
    }

    @Override
    public void afterSingletonsInstantiated() {
        this.serverCreator = context.getBean(MqttServerCreator.class);
    }

    @Override
    public void destroy() throws Exception {
        redisCache.del(getPlayerStatusRedisKey());
        Set<String> keys = redisCache.keys(getPlayerTimeRedisKey() + "*");
        keys.stream().forEach(k -> {
            redisCache.del(k);
        });

    }
}
